package mangabot.daos;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mangabot.pojos.Manga;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;

/**
 * Logic to retrieve and manipulate {@link Manga} information.
 *
 * @author Andrew Feller (andrew.feller@gmail.com)
 */
public class MangaDAO {

    private static final Logger logger = Logger.getLogger(MangaDAO.class);
    
    private static final Pattern PATTERN_ARTIST = Pattern.compile("Artist: <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>");

    private static final Pattern PATTERN_AUTHOR = Pattern.compile("Author: <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>");

    private static final Pattern PATTERN_CATEGORIES = Pattern.compile("Categories: <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>(, <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>)?(, <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>)?(, <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>)?(, <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>)?(, <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>)?(, <span class=\"series-info\"><a href=\".+?\">(.+?)</a></span>)?");

    private static final Pattern PATTERN_LISTING = Pattern.compile("<td class=\"ch-subject\"><a href=\"(.+?)\".+?>(.+?)</a>");

    private static final Pattern PATTERN_LOGO = Pattern.compile("<div class=\"title-logo\"><a href=\".+?\"><img src=\"(.+?)\"");

    private static final Pattern PATTERN_TITLE = Pattern.compile("Title: <span class=\"series-info\">(.+?)</span>");

    private static final Pattern PATTERN_RANK = Pattern.compile("OM Rank: <span class=\"series-info\">(.+?)</span>");

    private static final Pattern PATTERN_SUMMARY = Pattern.compile("<h3>Summary</h3>\\s+<div><p>(.+?)</p></div>");

    private static final String URL_ONEMANGA = "http://www.onemanga.com";

    private static final String URL_ONEMANGA_LISTING = URL_ONEMANGA + "/directory/";

    public List<Manga> retrieveListing() {

        List<Manga> mangas = new ArrayList<Manga>();

        HttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(URL_ONEMANGA_LISTING);

        try {
            logger.debug("Attempting to retrieve manga listing to parse");
            HttpResponse response = httpClient.execute(request);
            HttpEntity entity = response.getEntity();
            String content = IOUtils.toString(entity.getContent());

            Matcher matcher = PATTERN_LISTING.matcher(content);

            while (matcher.find()) {
                
                logger.trace("Found manga while parsing; title [" + matcher.group(2) + "], directory [" + matcher.group(1) + "]");
                Manga manga = new Manga();
                mangas.add(manga);

                manga.setDirectory(matcher.group(1));
                manga.setTitle(matcher.group(2));
            }

        } catch (Throwable t) {
            logger.error("Unable to retrieve manga listing; URL [" + URL_ONEMANGA_LISTING + "]", t);
        } finally {
            // Determine what cleanup is necessary
        }

        return mangas;
    }

    public Manga retrieveManga(String directory) {

        Manga manga = new Manga();
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(URL_ONEMANGA + directory);

        try {
            HttpResponse response = httpClient.execute(request);
            HttpEntity entity = response.getEntity();
            String content = IOUtils.toString(entity.getContent());

            Matcher matcher = PATTERN_ARTIST.matcher(content);

            if (matcher.find()) {
                manga.setArtist(matcher.group(1));
            }

            matcher = PATTERN_AUTHOR.matcher(content);

            if (matcher.find()) {
                manga.setAuthor(matcher.group(1));
            }

            manga.setCategories(new ArrayList<String>());
            manga.setDirectory(directory);

            matcher = PATTERN_LOGO.matcher(content);

            if (matcher.find()) {
                manga.setLogo(matcher.group(1));
            }

            matcher = PATTERN_RANK.matcher(content);

            if (matcher.find()) {
                manga.setRank(Integer.valueOf(matcher.group(1)));
            }

            matcher = PATTERN_SUMMARY.matcher(content);

            if (matcher.find()) {
                manga.setSummary(matcher.group(1));
            }

            matcher = PATTERN_TITLE.matcher(content);

            if (matcher.find()) {
                manga.setTitle(matcher.group(1));
            }

            matcher = PATTERN_CATEGORIES.matcher(content);

            while (matcher.find()) {
                for (int i = 1; i < matcher.groupCount(); i+= 2) {

                    String category = matcher.group(i);

                    if (!StringUtils.isBlank(category)) {
                        manga.getCategories().add(category);
                    }
                }
            }

        } catch (Throwable t) {
            logger.error("Unable to retrieve manga directory; URL [" + URL_ONEMANGA + directory + "]", t);
        }

        return manga;
    }
}
